package com.yuanian.timingwheel.model.timingwheel.bucket;

import com.yuanian.timingwheel.context.ExecutionContext;
import com.yuanian.timingwheel.context.SpringContext;
import com.yuanian.timingwheel.model.task.base.BaseTask;
import com.yuanian.timingwheel.redis.RedisServiceImpl;
import com.yuanian.timingwheel.threadpool.ThreadPoolExecutorFacade;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 时间轮上的槽,map实现
 */
public class BucketMap implements Bucket, Serializable {

    private Map<Long, BaseTask> taskMap;

    //任务已经被暂停的taskId集合
    private Set<Long> suspendTaskIdSet;

    //当前轮次
    private int round;

    public BucketMap(int round) {
        this.round = round;
        this.taskMap = new ConcurrentHashMap<>();
        this.suspendTaskIdSet = new HashSet<>();
    }

    @Override
    public void push(BaseTask e) {
        this.taskMap.put(e.getId(), e);
        //SpringContext.getBean(RedisServiceImpl.class).putBucket(this.round, this);
        ExecutionContext.getInstance().getDayTimingWheel().getBuckets().put(this.round, this);
    }

    @Override
    public void deletedTaskId(Long taskId) {
        this.taskMap.remove(taskId);
        ExecutionContext.getInstance().getDayTimingWheel().getBuckets().put(this.round, this);
    }

    @Override
    public void suspendTaskId(Long taskId) {
        suspendTaskIdSet.add(taskId);
        ExecutionContext.getInstance().getDayTimingWheel().getBuckets().put(this.round, this);
    }

    @Override
    public void consumeTaskId(Long taskId) {
        suspendTaskIdSet.remove(taskId);
        ExecutionContext.getInstance().getDayTimingWheel().getBuckets().put(this.round, this);
    }

    public boolean isEmpty(){
        return this.taskMap == null || this.taskMap.isEmpty();
    }

    @Override
    public boolean isCompleted() {
        if (isEmpty()) {
            return true;
        }
        for (BaseTask e : taskMap.values()) {
            if (!suspendTaskIdSet.contains(e.getId())) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean executeTask() {
        boolean result = true;
        for (Map.Entry<Long, BaseTask>  task : taskMap.entrySet()) {
            BaseTask cur = task.getValue();
            //任务没有被删除或暂停
            if (!suspendTaskIdSet.contains(cur.getId())) {
                ThreadPoolExecutorFacade.getInstance().execute(cur);
                taskMap.remove(cur.getId());
                //更新完回写
            } else if (suspendTaskIdSet.contains(cur.getId())) {
                result = false;
            }
        }
        //删除
        ExecutionContext.getInstance().getDayTimingWheel().getBuckets().remove(this.round);
        return result;
    }

    public static void main(String[] args) {
        Map<Integer, Integer> taskMap = new ConcurrentHashMap<>();
        taskMap.put(1, 1);
        taskMap.put(2, 2);
        taskMap.put(3, 3);
        for (Map.Entry a : taskMap.entrySet()) {
            System.out.println(a.getKey());
            taskMap.remove(a.getKey());
        }

        System.out.println(taskMap.size());
    }
}
